#!/usr/bin/perl
use Test::More;

BEGIN {
    # check if ip xfrm supports ctx parameter
    if (system("ip xfrm policy help 2>&1 | grep ctx") != 0) {
        plan skip_all => "ctx not supported in ip xfrm policy";
    } else {
        plan tests => 20;
    }
}

$basedir = $0;  $basedir =~ s|(.*)/[^/]*|$1|;

# Load NetLabel configuration.
system "$basedir/netlabel-load";

# Start the stream server.
if (($pid = fork()) == 0) {
    exec "runcon -t test_inet_server_t $basedir/server stream 65535";
}

sleep 1; # Give it a moment to initialize.

# Verify that authorized client can communicate with the server.
$result = system "runcon -t test_inet_client_t $basedir/client stream 65535";
ok($result eq 0);

# Verify that unauthorized client cannot communicate with the server.
$result = system "runcon -t test_inet_bad_client_t -- $basedir/client stream 65535 2>&1";
ok($result);

# Kill the server.
kill TERM, $pid;

# Start the dgram server.
if (($pid = fork()) == 0) {
    exec "runcon -t test_inet_server_t $basedir/server dgram 65535";
}

sleep 1; # Give it a moment to initialize

# Verify that authorized client can communicate with the server.
$result = system "runcon -t test_inet_client_t $basedir/client dgram 65535";
ok($result eq 0);

# Verify that unauthorized client cannot communicate with the server.
$result = system "runcon -t test_inet_bad_client_t -- $basedir/client dgram 65535 2>&1";
ok($result);

# Kill the server.
kill TERM, $pid;

# Flush NetLabel configuration.
system "$basedir/netlabel-flush";

# Verify that authorized domain can bind UDP sockets.
$result = system "runcon -t test_inet_bind_t -- $basedir/bind dgram 65535 2>&1";
ok($result eq 0);

# Verify that authorized domain can bind TCP sockets.
$result = system "runcon -t test_inet_bind_t -- $basedir/bind stream 65535 2>&1";
ok($result eq 0);

# Verify that domain without name_bind cannot bind UDP sockets.
$result = system "runcon -t test_inet_no_name_bind_t -- $basedir/bind dgram 65535 2>&1";
ok($result);

# Verify that domain without name_bind cannot bind TCP sockets.
$result = system "runcon -t test_inet_no_name_bind_t -- $basedir/bind stream 65535 2>&1";
ok($result);

# Verify that domain without node_bind cannot bind UDP sockets.
$result = system "runcon -t test_inet_no_node_bind_t -- $basedir/bind dgram 65535 2>&1";
ok($result);

# Verify that domain without node_bind cannot bind TCP sockets.
$result = system "runcon -t test_inet_no_node_bind_t -- $basedir/bind stream 65535 2>&1";
ok($result);

# Verify that authorized domain can connect to TCP socket.
$result = system "runcon -t test_inet_connect_t -- $basedir/connect 65535 2>&1";
ok($result eq 0);

# Verify that domain without name_connect cannot connect to TCP socket.
$result = system "runcon -t test_inet_no_name_connect_t -- $basedir/connect 65535 2>&1";
ok($result);

# Load IPSEC configuration.
system "$basedir/ipsec-load";

# Start the stream server.
if (($pid = fork()) == 0) {
    exec "runcon -t test_inet_server_t $basedir/server stream 65535";
}

sleep 1; # Give it a moment to initialize.

# Verify that authorized client can communicate with the server.
$result = system "runcon -t test_inet_client_t $basedir/client stream 65535";
ok($result eq 0);

# Verify that unauthorized client cannot communicate with the server.
$result = system "runcon -t test_inet_bad_client_t -- $basedir/client stream 65535 2>&1";
ok($result);

# Kill the server.
kill TERM, $pid;

# Start the dgram server.
if (($pid = fork()) == 0) {
    exec "runcon -t test_inet_server_t $basedir/server dgram 65535";
}

sleep 1; # Give it a moment to initialize

# Verify that authorized client can communicate with the server.
$result = system "runcon -t test_inet_client_t $basedir/client dgram 65535";
ok($result eq 0);

# Verify that unauthorized client cannot communicate with the server.
$result = system "runcon -t test_inet_bad_client_t -- $basedir/client dgram 65535 2>&1";
ok($result);

# Kill the server.
kill TERM, $pid;

# Flush IPSEC configuration.
system "$basedir/ipsec-flush";

# Load iptables configuration.
system "$basedir/iptables-load";

# Start the stream server.
if (($pid = fork()) == 0) {
    exec "runcon -t test_inet_server_t -- $basedir/server -n stream 65535";
}

sleep 1; # Give it a moment to initialize.

# Verify that authorized client can communicate with the server.
$result = system "runcon -t test_inet_client_t -- $basedir/client -n stream 65535";
ok($result eq 0);

# Verify that unauthorized client cannot communicate with the server.
$result = system "runcon -t test_inet_bad_client_t -- $basedir/client -n stream 65535 2>&1";
ok($result);

# Kill the server.
kill TERM, $pid;

# Start the dgram server.
if (($pid = fork()) == 0) {
    exec "runcon -t test_inet_server_t $basedir/server -n dgram 65535";
}

sleep 1; # Give it a moment to initialize

# Verify that authorized client can communicate with the server.
$result = system "runcon -t test_inet_client_t $basedir/client -n dgram 65535";
ok($result eq 0);

# Verify that unauthorized client cannot communicate with the server.
$result = system "runcon -t test_inet_bad_client_t -- $basedir/client -n dgram 65535 2>&1";
ok($result);

# Kill the server.
kill TERM, $pid;

# Flush iptables configuration.
system "$basedir/iptables-flush";

exit;
